home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
- #include <GL/gl.h>
- #include <GL/glx.h>
- #include <X11/Xlib.h>
- #include <X11/keysym.h>
-
- #define TWO_PI (2*M_PI)
-
- typedef struct lightRec {
- float amb[4];
- float diff[4];
- float spec[4];
- float pos[4];
- float spotDir[3];
- float spotExp;
- float spotCutoff;
- float atten[3];
-
- float trans[3];
- float rot[3];
- float swing[3];
- float arc[3];
- float arcIncr[3];
- } Light;
-
- static int useSAME_AMB_SPEC = 1;
-
- static float modelAmb[4] = { 0.2, 0.2, 0.2, 1.0 };
-
- static float matAmb[4] = { 0.2, 0.2, 0.2, 1.0 };
- static float matDiff[4] = { 0.8, 0.8, 0.8, 1.0 };
- static float matSpec[4] = { 0.4, 0.4, 0.4, 1.0 };
- static float matEmission[4] = { 0.0, 0.0, 0.0, 1.0 };
-
- static char *geometry = NULL;
-
- #define NUM_LIGHTS 3
- static Light spots[] = {
- {
- { 0.2, 0.0, 0.0, 1.0 }, /* ambient */
- { 0.8, 0.0, 0.0, 1.0 }, /* diffuse */
- { 0.4, 0.0, 0.0, 1.0 }, /* specular */
- { 0.0, 0.0, 0.0, 1.0 }, /* position */
- { 0.0, -1.0, 0.0 }, /* direction */
- { 20.0 }, { 60.0 }, /* exponent, cutoff */
- { 1.0, 0.0, 0.0 }, /* attenuation */
- { 0.0, 1.25, 0.0 }, /* translation */
- { 0.0, 0.0, 0.0 }, /* rotation */
- { 20.0, 0.0, 40.0 }, /* swing */
- { 0.0, 0.0, 0.0 }, /* arc */
- { TWO_PI/70.0, 0.0, TWO_PI/140.0 } /* arc increment */
- },
- {
- { 0.0, 0.2, 0.0, 1.0 }, /* ambient */
- { 0.0, 0.8, 0.0, 1.0 }, /* diffuse */
- { 0.0, 0.4, 0.0, 1.0 }, /* specular */
- { 0.0, 0.0, 0.0, 1.0 }, /* position */
- { 0.0, -1.0, 0.0 }, /* direction */
- { 20.0 }, { 60.0 }, /* exponent, cutoff */
- { 1.0, 0.0, 0.0 }, /* attenuation */
- { 0.0, 1.25, 0.0 }, /* translation */
- { 0.0, 0.0, 0.0 }, /* rotation */
- { 20.0, 0.0, 40.0 }, /* swing */
- { 0.0, 0.0, 0.0 }, /* arc */
- { TWO_PI/120.0, 0.0, TWO_PI/60.0 } /* arc increment */
- },
- {
- { 0.0, 0.0, 0.2, 1.0 }, /* ambient */
- { 0.0, 0.0, 0.8, 1.0 }, /* diffuse */
- { 0.0, 0.0, 0.4, 1.0 }, /* specular */
- { 0.0, 0.0, 0.0, 1.0 }, /* position */
- { 0.0, -1.0, 0.0 }, /* direction */
- { 20.0 }, { 60.0 }, /* exponent, cutoff */
- { 1.0, 0.0, 0.0 }, /* attenuation */
- { 0.0, 1.25, 0.0 }, /* translation */
- { 0.0, 0.0, 0.0 }, /* rotation */
- { 20.0, 0.0, 40.0 }, /* swing */
- { 0.0, 0.0, 0.0 }, /* arc */
- { TWO_PI/50.0, 0.0, TWO_PI/100.0 } /* arc increment */
- }
- };
-
- static void
- usage(int argc, char **argv)
- {
- printf("\n");
- printf("usage: %s [options]\n", argv[0]);
- printf("\n");
- printf(" Options:\n");
- printf(" -geometry Specify size and position WxH+X+Y\n");
- printf(" -lm Toggle lighting(SPECULAR and AMBIENT are/not same\n");
- printf("\n");
- exit(EXIT_FAILURE);
- }
-
- static void
- initLights(void)
- {
- int k;
-
- for (k=0; k<NUM_LIGHTS; ++k) {
- int lt = GL_LIGHT0+k;
- Light *light = &spots[k];
-
- glEnable(lt);
- glLightfv(lt, GL_AMBIENT, light->amb);
- glLightfv(lt, GL_DIFFUSE, light->diff);
-
- if (useSAME_AMB_SPEC)
- glLightfv(lt, GL_SPECULAR, light->amb);
- else
- glLightfv(lt, GL_SPECULAR, light->spec);
-
- glLightf(lt, GL_SPOT_EXPONENT, light->spotExp);
- glLightf(lt, GL_SPOT_CUTOFF, light->spotCutoff);
- glLightf(lt, GL_CONSTANT_ATTENUATION, light->atten[0]);
- glLightf(lt, GL_LINEAR_ATTENUATION, light->atten[1]);
- glLightf(lt, GL_QUADRATIC_ATTENUATION, light->atten[2]);
- }
- }
-
- static void
- aimLights(void)
- {
- int k;
-
- for (k=0; k<NUM_LIGHTS; ++k) {
- Light *light = &spots[k];
-
- light->rot[0] = light->swing[0] * sin(light->arc[0]);
- light->arc[0] += light->arcIncr[0];
- if (light->arc[0] > TWO_PI) light->arc[0] -= TWO_PI;
-
- light->rot[1] = light->swing[1] * sin(light->arc[1]);
- light->arc[1] += light->arcIncr[1];
- if (light->arc[1] > TWO_PI) light->arc[1] -= TWO_PI;
-
- light->rot[2] = light->swing[2] * sin(light->arc[2]);
- light->arc[2] += light->arcIncr[2];
- if (light->arc[2] > TWO_PI) light->arc[2] -= TWO_PI;
- }
- }
-
- static void
- setLights(void)
- {
- int k;
-
- for (k=0; k<NUM_LIGHTS; ++k) {
- int lt = GL_LIGHT0+k;
- Light *light = &spots[k];
-
- glPushMatrix();
- glTranslatef(light->trans[0], light->trans[1], light->trans[2]);
- glRotatef(light->rot[0], 1, 0, 0);
- glRotatef(light->rot[1], 0, 1, 0);
- glRotatef(light->rot[2], 0, 0, 1);
- glLightfv(lt, GL_POSITION, light->pos);
- glLightfv(lt, GL_SPOT_DIRECTION, light->spotDir);
- glPopMatrix();
- }
- }
-
- static void
- drawLights(void)
- {
- int k;
-
- glDisable(GL_LIGHTING);
- for (k=0; k<NUM_LIGHTS; ++k) {
- Light *light = &spots[k];
-
- glColor4fv(light->diff);
-
- glPushMatrix();
- glTranslatef(light->trans[0], light->trans[1], light->trans[2]);
- glRotatef(light->rot[0], 1, 0, 0);
- glRotatef(light->rot[1], 0, 1, 0);
- glRotatef(light->rot[2], 0, 0, 1);
- glBegin(GL_LINES);
- glVertex3f(light->pos[0], light->pos[1], light->pos[2]);
- glVertex3f(light->spotDir[0], light->spotDir[1], light->spotDir[2]);
- glEnd();
- glPopMatrix();
- }
- glEnable(GL_LIGHTING);
- }
-
- static void
- drawPlane(int w, int h)
- {
- int i, j;
- float dw = 1.0/w;
- float dh = 1.0/h;
-
- glNormal3f(0.0, 0.0, 1.0);
- for (j=0; j<h; ++j) {
- glBegin(GL_TRIANGLE_STRIP);
- for (i=0; i<=w; ++i) {
- glVertex2f(dw * i, dh * (j+1));
- glVertex2f(dw * i, dh * j);
- }
- glEnd();
- }
- }
-
- static Bool
- waitForNotify(Display *dpy, XEvent *event, XPointer arg)
- {
- return (event->type == MapNotify && event->xmap.window == (Window) arg);
- }
-
- static void
- windopen(Display **dpy_ret, Window *win_ret, GLXContext *ctx_ret,
- char *name, int w, int h, int argc, char **argv)
- {
- static int visAttrs[] = {
- GLX_RGBA,
- GLX_DOUBLEBUFFER,
- GLX_RED_SIZE, 1,
- GLX_GREEN_SIZE, 1,
- GLX_BLUE_SIZE, 1,
- None
- };
- static Display *dpy = NULL;
- int scr;
- Window root;
- XVisualInfo *xvis;
- GLXContext ctx;
- XSetWindowAttributes xswa;
- XSizeHints sizehints;
- Colormap cmap;
- Window win;
- XEvent event;
-
- if (dpy == NULL) {
- if ((dpy = XOpenDisplay(NULL)) == NULL) {
- fprintf(stderr, "can't open display\n");
- exit(EXIT_FAILURE);
- }
- }
- scr = DefaultScreen(dpy);
- root = RootWindow(dpy, scr);
-
- if ((xvis = glXChooseVisual(dpy, scr, visAttrs)) == NULL) {
- fprintf(stderr, "can't find visual\n");
- exit(EXIT_FAILURE);
- }
-
- if ((ctx = glXCreateContext(dpy, xvis, NULL, True)) == None) {
- fprintf(stderr, "can't create context\n");
- exit(EXIT_FAILURE);
- }
-
- if ((cmap = XCreateColormap(dpy, root, xvis->visual, AllocNone)) == None) {
- fprintf(stderr, "can't create colormap\n");
- exit(EXIT_FAILURE);
- }
-
- sizehints.flags = PPosition | PSize;
- sizehints.width = w;
- sizehints.height = h;
- sizehints.x = 0;
- sizehints.y = 0;
- if (geometry) {
- int flags, x, y, width, height;
-
- flags = XParseGeometry(geometry, &x, &y,
- (unsigned int *)&width,
- (unsigned int *)&height);
- if(WidthValue & flags) {
- sizehints.flags |= USSize;
- sizehints.width = width;
- w = width;
- }
- if(HeightValue & flags) {
- sizehints.flags |= USSize;
- sizehints.height = height;
- h = height;
- }
- if(XValue & flags) {
- if(XNegative & flags)
- x = DisplayWidth(dpy, DefaultScreen(dpy)) + x
- - sizehints.width;
- sizehints.flags |= USPosition;
- sizehints.x = x;
- }
- if(YValue & flags) {
- if(YNegative & flags)
- y = DisplayHeight(dpy, DefaultScreen(dpy)) + y
- - sizehints.height;
- sizehints.flags |= USPosition;
- sizehints.y = y;
- }
- }
- xswa.colormap = cmap;
- xswa.background_pixel = 0;
- xswa.border_pixel = 0;
- xswa.event_mask = KeyPressMask | ExposureMask | StructureNotifyMask;
- win = XCreateWindow(dpy, root, sizehints.x, sizehints.y,
- sizehints.width, sizehints.height, 0,
- xvis->depth, InputOutput, xvis->visual,
- CWColormap | CWBackPixel | CWBorderPixel | CWEventMask,
- &xswa);
-
- XSetStandardProperties(dpy, win, name, name, None,
- argv, argc, &sizehints);
-
- XMapWindow(dpy, win);
- XIfEvent(dpy, &event, waitForNotify, (XPointer) win);
-
- glXMakeCurrent(dpy, win, ctx);
-
- *dpy_ret = dpy;
- *win_ret = win;
- *ctx_ret = ctx;
- }
-
- int
- main(int argc, char **argv)
- {
- Display *dpy;
- Window win;
- GLXContext ctx;
- int width = 300, height = 300;
- float spin = 0.0;
- int i;
-
- /* process commmand line args */
- for (i = 1; i < argc; ++i)
- {
- if (!strcmp("-geometry", argv[i]))
- {
- i++;
- geometry = argv[i];
- if (geometry == NULL) {
- usage(argc, argv);
- }
- }
- else if (!strcmp("-lm", argv[i]))
- {
- useSAME_AMB_SPEC = !useSAME_AMB_SPEC;
- }
- else
- {
- usage(argc, argv);
- }
- }
-
- windopen(&dpy, &win, &ctx, "spotlight swing", width, height, argc, argv);
-
- glMatrixMode(GL_PROJECTION);
- glFrustum(-1, 1, -1, 1, 2, 6);
-
- glMatrixMode(GL_MODELVIEW);
- glTranslatef(0.0, 0.0, -3.0);
- glRotatef(45.0, 1, 0, 0);
-
- glEnable(GL_LIGHTING);
- glEnable(GL_NORMALIZE);
-
- glLightModelfv(GL_LIGHT_MODEL_AMBIENT, modelAmb);
- glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
- glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
-
- glMaterialfv(GL_FRONT, GL_AMBIENT, matAmb);
- glMaterialfv(GL_FRONT, GL_DIFFUSE, matDiff);
- glMaterialfv(GL_FRONT, GL_SPECULAR, matSpec);
- glMaterialfv(GL_FRONT, GL_EMISSION, matEmission);
- glMaterialf(GL_FRONT, GL_SHININESS, 10.0);
-
- initLights();
-
- while (1) {
- if (XPending(dpy)) {
- XEvent event;
- KeySym ks;
-
- XNextEvent(dpy, &event);
- switch(event.type) {
- case KeyPress:
- XLookupString(&event.xkey, NULL, 0, &ks, NULL);
- if (ks == XK_Escape) {
- exit(EXIT_SUCCESS);
- }
- break;
- case ConfigureNotify:
- width = event.xconfigure.width;
- height = event.xconfigure.height;
- glViewport(0, 0, width, height);
- break;
- default:
- break;
- }
- }
-
- glClear(GL_COLOR_BUFFER_BIT);
-
- glPushMatrix();
- glRotatef(spin += 0.5, 0, 1, 0);
- if (spin > 360.0) spin -= 360.0;
-
- aimLights();
- setLights();
-
- glPushMatrix();
- glRotatef(-90.0, 1, 0, 0);
- glScalef(1.9, 1.9, 1.0);
- glTranslatef(-0.5, -0.5, 0.0);
- drawPlane(16, 16);
- glPopMatrix();
-
- drawLights();
- glPopMatrix();
-
- glXSwapBuffers(dpy, win);
- }
- }
-